package cl.loso.melon.server.persistencia;

import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import cl.loso.melon.server.gae.PMF;
import cl.loso.melon.server.model.MetaLVS;
import cl.loso.melon.server.model.UsuarioLVS;
import cl.loso.melon.server.model.VisitaLVS;
import cl.loso.melon.server.negocio.UsuarioLVSBO;

public class MetaLVSDAO {
	private static Log log = LogFactory.getLog(MetaLVSDAO.class);

	@SuppressWarnings("unchecked")
	public static List<MetaLVS> obtener(String idUsuario) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		UsuarioLVS usuario = null;
		List<MetaLVS> detached = null;
		Query query = null;
		try {
			usuario = pm.getObjectById(UsuarioLVS.class,
					Long.valueOf(idUsuario));

			Map<String, Object> pars = new HashMap<String, Object>();
			String queryStr = "usuario == :usr";

			pars.put("usr", usuario);

			query = pm.newQuery(MetaLVS.class);
			query.setFilter(queryStr);

			detached = (List<MetaLVS>) pm.detachCopyAll((List<MetaLVS>) query
					.executeWithMap(pars));

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return detached;

	}

	@SuppressWarnings("unchecked")
	public static List<MetaLVS> obtener(Long idUsuario, Integer ano) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		UsuarioLVS usuario = null;
		List<MetaLVS> detached = null;
		Query query = null;
		try {
			usuario = pm.getObjectById(UsuarioLVS.class, idUsuario);

			Map<String, Object> pars = new HashMap<String, Object>();

			String queryStr = "usuario == :usr && ano==:ano";
			pars.put("usr", usuario);
			pars.put("ano", ano);
			query = pm.newQuery(MetaLVS.class);
			query.setFilter(queryStr);

			detached = (List<MetaLVS>) pm.detachCopyAll((List<MetaLVS>) query
					.executeWithMap(pars));

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return detached;

	}

	@SuppressWarnings("unchecked")
	public static Float obtenerLaMeta(Date fecha, UsuarioLVS usuario) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = null;
		float meta = 0;
		try {

			Calendar calendar = Calendar.getInstance();
			calendar.setTime(fecha);

			Map<String, Object> pars = new HashMap<String, Object>();
			String queryStr = "mes == :mes && ano==:ano && usuario == :usr";
			pars.put("ano", calendar.get(Calendar.YEAR));
			pars.put("mes", calendar.get(Calendar.MONTH));
			pars.put("usr", usuario);

			query = pm.newQuery(MetaLVS.class);
			query.setFilter(queryStr);

			MetaLVS lameta = ((List<MetaLVS>) pm
					.detachCopyAll((List<MetaLVS>) query.executeWithMap(pars)))
					.get(0);
			meta = lameta.getMeta();

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return meta;

	}

	@SuppressWarnings("unchecked")
	public static Float obtenerTotalMeta(Date fecha_ini, Date fecha_ter,
			UsuarioLVS usuario) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = null;
		float lameta = 0;
		try {

			Map<String, Object> pars = new HashMap<String, Object>();
			String queryStr = "fecha >= :fecini && fecha <= :fecter && usuario == :usr";
			pars.put("fecini", fecha_ini);
			pars.put("fecter", fecha_ter);
			pars.put("usr", usuario);

			query = pm.newQuery(MetaLVS.class);
			query.setFilter(queryStr);

			List<MetaLVS> metas = (List<MetaLVS>) pm
					.detachCopyAll((List<MetaLVS>) query.executeWithMap(pars));

			if (metas != null && !metas.isEmpty()) {
				for (MetaLVS meta : metas) {
					lameta += meta.getMeta().floatValue();
				}
			}

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return lameta;
	}

	@SuppressWarnings("unchecked")
	public static int obtenerTotalMeta(Date fecha_ini, Date fecha_ter,
			Long idUsuario) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = null;
		int lameta = 0;
		try {
			UsuarioLVS usuario = UsuarioLVSBO.editarUsuario(idUsuario);

			Map<String, Object> pars = new HashMap<String, Object>();
			String queryStr = "fecha >= :fecini && fecha <= :fecter && usuario == :usr";
			pars.put("fecini", fecha_ini);
			pars.put("fecter", fecha_ter);
			pars.put("usr", usuario);

			query = pm.newQuery(MetaLVS.class);
			query.setFilter(queryStr);

			List<MetaLVS> metas = (List<MetaLVS>) pm
					.detachCopyAll((List<MetaLVS>) query.executeWithMap(pars));


			if (metas != null && !metas.isEmpty()) {
				for (MetaLVS meta : metas) {
					lameta += meta.getMeta().floatValue();
				}
			}


		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return lameta;
	}

	@SuppressWarnings("unchecked")
	public static int obtenerTotalMetaGerencia(Date fecha_ini, Date fecha_ter,
			Long idGerencia) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = null;
		int lameta = 0;
		try {

			List<UsuarioLVS> usuarioLst = UsuarioLVSDAO
					.buscarUsuarioPorGerencia(idGerencia);
			for (UsuarioLVS usuario : usuarioLst) {

				Map<String, Object> pars = new HashMap<String, Object>();
				String queryStr = "fecha >= :fecini && fecha <= :fecter && usuario == :usr";
				pars.put("fecini", fecha_ini);
				pars.put("fecter", fecha_ter);
				pars.put("usr", usuario);

				query = pm.newQuery(MetaLVS.class);
				query.setFilter(queryStr);

				List<MetaLVS> metas = (List<MetaLVS>) pm
						.detachCopyAll((List<MetaLVS>) query
								.executeWithMap(pars));


				if (metas != null && !metas.isEmpty()) {
					for (MetaLVS meta : metas) {
						lameta += meta.getMeta().floatValue();
					}
				}

			}


		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return lameta;
	}

	@SuppressWarnings("unchecked")
	public static String[] obtenerDuracionVisita(Date fecha_ini,
			Date fecha_ter, Long idUsuario, int meta) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		Query query = null;

		double duracion = 0;
		long totduracion = 0;
		long totseguros = 0;
		long totinseguros = 0;
		double cumplimiento = 0;
		String[] retorno = new String[4];
		try {
			UsuarioLVS usuario = UsuarioLVSBO.editarUsuario(idUsuario);

			Map<String, Object> pars = new HashMap<String, Object>();
			String queryStr = "fecha >= :fecini && fecha <= :fecter && usuario == :usr";
			pars.put("fecini", fecha_ini);
			pars.put("fecter", fecha_ter);
			pars.put("usr", usuario);

			query = pm.newQuery(VisitaLVS.class);
			query.setFilter(queryStr);

			List<VisitaLVS> visitas = (List<VisitaLVS>) pm
					.detachCopyAll((List<VisitaLVS>) query.executeWithMap(pars));


			DecimalFormat formateador = new DecimalFormat("###.#%");
			DecimalFormat df = new DecimalFormat("#0");

			for (VisitaLVS visita : visitas) {

				totduracion = totduracion + visita.getDuracion().longValue();
				totseguros = totseguros + visita.getTseguro().longValue();
				totinseguros = totinseguros + visita.getTinseguro().longValue();

			}

			duracion = (double) totduracion / 3600000;
			retorno[0] = df.format(duracion);

			if (meta != 0) {
				cumplimiento = duracion / (double) meta;// meta del periodo
			}

			retorno[1] = formateador.format(cumplimiento);
			retorno[2] = String.valueOf(totseguros);
			retorno[3] = String.valueOf(totinseguros);

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return retorno;
	}

	public static void insertar(UsuarioLVS usuarioLVS) {
		Transaction tx = null;
		PersistenceManager pm = PMF.get().getPersistenceManager();
		try {
			tx = pm.currentTransaction();
			tx.begin();
			pm.makePersistent(usuarioLVS);

			tx.commit();
		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			if (tx.isActive()) {
				tx.rollback();
			}
			if (!pm.isClosed()) {
				pm.close();
			}
		}
	}


	@SuppressWarnings("unchecked")
	public static List<MetaLVS> getMetaLVS(Long idUsuario) {
		PersistenceManager pm = PMF.get().getPersistenceManager();
		List<MetaLVS> detached = null;
		Query query = null;
		try {
			UsuarioLVS usr = UsuarioLVSDAO.getUsuarioLVSbyId(idUsuario);
			query = pm.newQuery(MetaLVS.class);
			query.setFilter("usuario==:usr");

			Map<String, Object> pars = new HashMap<String, Object>();
			pars.put("usr", usr);

			detached = (List<MetaLVS>) pm.detachCopyAll((List<MetaLVS>) query
					.executeWithMap(pars));

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
		return detached;
	}

	@SuppressWarnings("unchecked")
	public static void actualizar(Long idUsuario, Integer ano, Integer mes,
			Float horas) {

		PersistenceManager pm = PMF.get().getPersistenceManager();
		MetaLVS meta = null;
		Query query = null;
		try {

			UsuarioLVS usr = UsuarioLVSDAO.getUsuarioLVSbyId(idUsuario);
			query = pm.newQuery(MetaLVS.class);
			query.setFilter("usuario==:usr && ano == :ano && mes == :mes");

			Map<String, Object> pars = new HashMap<String, Object>();
			pars.put("usr", usr);
			pars.put("ano", ano);
			pars.put("mes", mes);

			meta = ((List<MetaLVS>) query.executeWithMap(pars)).get(0);
			meta.setMeta(horas);

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
	}

	@SuppressWarnings("unchecked")
	public static void borrar(Long idUsuario, Integer ano) {
		PersistenceManager pm = PMF.get().getPersistenceManager();

		Iterator<MetaLVS> iteMeta = null;
		Query query = null;
		try {

			UsuarioLVS usr = UsuarioLVSDAO.getUsuarioLVSbyId(idUsuario);
			query = pm.newQuery(MetaLVS.class);
			query.setFilter("usuario==:usr && ano == :ano");

			Map<String, Object> pars = new HashMap<String, Object>();
			pars.put("usr", usr);
			pars.put("ano", ano);

			iteMeta = ((List<MetaLVS>) query.executeWithMap(pars)).iterator();

			while (iteMeta.hasNext()) {

				pm.deletePersistent(iteMeta.next());
			}

		} catch (Exception e) {
			log.error(e.getMessage());
		} finally {
			pm.close();
		}
	}

}
